import javax.annotation.concurrent.ThreadSafe;

@ThreadSafe
public class interface_not_thread_safe {
  public static void foo(I i) {
    i.bar(); // RacerD warns here
  }
}

// public class interface_not_thread_safe {
//   public static void foo() {
//     C c = new C();
//     c.foo(new unsafe_counter());
//   }
// }

// The way to fix this warning is to add a @ThreadSafe annotation to the
// interface I, which will enforce the thread-safety of each of the
// implementations of I.

// You might wonder why it's necessary to annotate I -- can't RacerD just look
// at all the implementations of i at the call site for bar? Although this is a
// fine idea in principle, it's a bad idea in practice due to a (a) separate
// compilation and (b) our diff-based deployment model. In the example above,
// the compiler doesn't have to know about all implementations (or indeed, any
// implementations) of I at the time it compiles this code, so there's no
// guarantee that RacerD will know about or be able to check all implementations
// of I. That's (a). For (b), say that we check that all implementations of I
// are thread-safe at the time this code is written, but we don't add the
// annotation. If someone else comes along and adds a new implementation of I
// that is not thread-safe, RacerD will have no way of knowing that this will
// cause a potential bug in foo. But if I is annotated, RacerD will enforce that
// all new implementations of I are thread-safe, and foo will remain bug-free.